package com.megurokai.paint;

import java.util.ArrayList;
import java.util.List;

import com.megurokai.command.Command;

public class HistoryManager {
	List<Command> listCommand;
	List<Integer> listCount;
	int counter;
	
	// コンストラクタ
	public HistoryManager(){
		listCommand = new ArrayList<Command>();
		listCount = new ArrayList<Integer>();
		listCount.add(new Integer(0));
		counter = 0;
	}
	
	// 履歴をクリアする
	public void clear(){
		listCommand.clear();
		listCount.clear();
		listCount.add(new Integer(0));
		counter = 0;
	}
	
	// コマンドをリストに追加する
	public void add(Command command){
		listCommand.add(command);
	}
	
	// コマンドを実行しながらリストに追加する
	public void addAndDraw(Command command, Status status){
		// 元に戻した状態でリストに追加する場合、
		// 現在の位置から最後尾までのアイテムを削除する
		if(counter < listCount.size()-1){
			List<Command> tmp = new ArrayList<Command>();
			
			for(int i=listCount.get(counter); i<listCommand.size(); i++){
				tmp.add(listCommand.get(i));
			}
			listCommand.removeAll(tmp);
			
			int loop = listCount.size()-1-counter;
			for(int i=0; i<loop; i++){
				listCount.remove(listCount.size()-1);
			}
		}
		
		add(command);
		
		// 描画コマンドが見た目上の１コマンドに相当するものならカウント値をインクリメント
		if(command.draw(status)){
			listCount.add(listCommand.size());
			counter++;
		}
	}
	
	// 最後のコマンドを渡されたコマンドで上書きする
	public void replace(Command command){
		listCommand.set(listCommand.size()-1, command);
		
		// 置き換えコマンドは必ずカウント値が増える
		listCount.add(listCommand.size());
		counter++;
	}
	
	// 最後のコマンドをわたされたコマンドで上書きする

	// コマンドを一件実行前に戻す
	public void undo(Status status){
		if(counter == 0){
			return;
		}
		
		Status tmpStatus = new Status();
		saveAttribute(status, tmpStatus);
		status.reset();
		
		counter--;
		for(int i=0; i<listCount.get(counter).intValue(); i++){
			listCommand.get(i).draw(tmpStatus);
		}
		
		saveAttribute(tmpStatus, status);
	}
	
	// 設定情報をコピーする
	public void saveAttribute(Status from, Status to){
		to.setColor(from.getColor());
		to.setAlpha(from.getAlpha());
		to.setStrokeWidth(from.getStrokeWidth());
	}
	// コマンドを一件再実行する
	public void redo(Status status){
		if(listCount.get(counter).intValue() == listCommand.size()){
			return ;
		}
		
		for(int i=listCount.get(counter).intValue(); i<listCount.get(counter+1); i++){
			listCommand.get(i).draw(status);
		}

		counter++;
	}
	
	// 全コマンドを実行
	public void draw(Status status){
		for(Command c : listCommand){
			c.draw(status);
		}
	}
}
